#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Author: leuelcey (wyd)
# E-mail: leuelcey@163.com
# Creation date: 2021.2
# Modified date: 2021.4

from math import ceil, floor, pi as PI
from functools import lru_cache
from datetime import datetime
from basicdata import BasicData
from tools import (deltaT, sun_alng, equation_of_time, Juday2timestring, Gregory2Juday, Juday2Gregory,
                        lng_lat_decode, get_timezone, mean_solar_time, get_keys, sVar as sv)
from annles import hq_24jieqi, Annles, hq_nl_nian, get_Week
from bagua import Bagua

bzbd = BasicData()
J2000 = bzbd.get_constant(section='astronomy', varname='J2000')
radian = bzbd.get_constant(section='astronomy', varname='radian_degree')
pi2 = bzbd.get_constant(section='astronomy', varname='pi_2times')

class Bazi(object):
    """
    八字类。
        人的生辰包含年、月、日、时辰这四个重要元素，称为`四柱`，每一柱由一个天干名和一个地支名
    组成，共八个字，因此也将四柱称为`八字`；每个人的生辰八字以日干为主，通过与其他干支进行阴阳
    五行的生克计算，排列出不同组合，分别称为`十神`、`长生`、`空亡`、`星煞`等等，用于对一个人的
    命和运进行批断。
    """
    __slots__ = ('__dict__', '__weakref__', 'jlJd', 'srJd', 'gans', 'zhis', 'xiao', 'shen', 'cgan', 'dztg', 
                'benq', 'tgdz', 'chsh', 'zodiac', 'nywx', 'zwx', 'gwx', 'flag', 'xysr', 'bgua', 'dnsr')

    def __init__(self):
        super(Bazi, self).__init__()
        self.jlJd = None
        self.srJd = None
        self.xysr = Annles()
        self.bgua = Bagua()
        self.flag = False
        self.dnsr = True
        self.gans = bzbd.get_constant(section='bazi', varname='gan')  # 天干
        self.zhis = bzbd.get_constant(section='bazi', varname='zhi')  # 地支
        self.xiao = bzbd.get_constant(section='bazi', varname='xiao')  # 生肖
        self.zodiac = bzbd.get_constant(section='calendar', varname='Zodiac')  # 星座
        self.shen = bzbd.get_constant(section='bazi', varname='shishen')  # 十神
        self.cgan = bzbd.get_constant(section='bazi', varname='cangan')  # 地支藏干
        self.dztg = bzbd.get_constant(section='bazi', varname='zhi_gan')  # 地支对应天干
        self.benq = bzbd.get_constant(section='bazi', varname='benqi')  # 本气
        self.tgdz = bzbd.get_constant(section='bazi', varname='gan_zhi')  # 天干对应地支
        self.chsh = bzbd.get_constant(section='bazi', varname='zhangsheng')  # 十二长生
        self.nywx = bzbd.get_constant(section='bazi', varname='nywx')  # 纳音对应五行
        self.zwx = bzbd.get_constant(section='bazi', varname='zhi_wx')  # 地支对应五行
        self.gwx = bzbd.get_constant(section='bazi', varname='gan_wx')  # 天干对应五行
        sv.Init()

    # 获取四柱，天干值、地支值，四柱的纳音，真太阳时间，当日各时辰干支纪时
    # 算法及源代码：许剑伟（莆田十中）
    # Python 代码：leuelcey (wyd)
    @lru_cache
    def hq_sizhu(self, jd, J):
        """
        取四柱及其干支值、纳音、真太阳时、当日干支纪时等信息。
        用法：Bazi.hq_sizhu(<儒略日数>, <经度>)
        :param jd: 儒略日数
        :param J: 经度
        :return: 设置各属性值
        """
        nayin = bzbd.get_constant(section='bazi', varname='nayin')

        jd2 = jd + deltaT(jd)
        w = sun_alng(jd2 / 36525, -1)
        k = floor((w / pi2 * 360 + 45 + 15 * 360) / 30)
        jd = jd + (equation_of_time(jd2 / 36525) + J / PI / 2)
        zty = Juday2timestring(jd)  # 真太阳时间串
        jd = jd + (13 / 24)
        D = floor(jd)
        SC = floor((jd - D) * 12)

        self.gan_zhi = {'gan': [0, 0, 0, 0], 'zhi': [0, 0, 0, 0]}
        self.sizhu = ['', '', '', '']
        self.nayin = ['', '', '', '']

        vx = [floor(k / 12 + 6000000), k + 2 + 60000000, D - 6 + 9000000, (D - 1) * 12 + 90000000 + SC]
        for i, vz in enumerate(vx):
            self.gan_zhi['gan'][i] = vz % 10
            self.gan_zhi['zhi'][i] = vz % 12
            self.sizhu[i] = self.gans[vz % 10] + self.zhis[vz % 12]
            self.nayin[i] = nayin[ceil((((60 + (vz + 1) % 60) % 60) / 2))]

        v = vx[3] - SC
        self.shichen = ''
        for i in range(13):
            c = self.gans[(v + i) % 10] + self.zhis[(v + i) % 12]
            self.shichen = self.shichen + ('  ' if i != 0 else '') + c
        self.Real_Sun = zty

    # by leuelcey (wyd)
    def hq_kw_Base(self, gan, zhi):
        """
        取空亡基本信息，后续将据此计算详细空亡信息。
        用法：kwb = hq_kw_Base(<天干值>, <地支值>)
        :param gan: 天干值
        :param zhi: 地支值
        :return: 空亡地支值及地支名的字典对象
        """
        kw1 = zhi - gan - 2
        if kw1 < 0:
            kw1 = kw1 + 12
        kw2 = kw1 + 1
        if kw2 == 12:
            kw2 = 0
        return {'zhis': (kw1, kw2), 'kongwang': self.zhis[kw1] + self.zhis[kw2]}

    # 取空亡
    # by leuelcey (wyd)
    def hq_kongwang(self, zhi=0):
        """
        取其他各空亡。
        :param zhi: 地支值
        :return: 空亡地支名
        """
        kwdz = self.kw_Base['zhis']
        if zhi in kwdz:
            return self.zhis[zhi]
        return ''

    # 获取节令信息
    # by leuelcey (wyd)
    def hq_jieling(self, Year=0):
        """
        节气中，月初的为节令，月中的为中气，合称为节气。本函数只取节令信息。
        用法：Bazi.hq_jieling([西元年])
        :param Year: 西元年
        :return: 设置节令属性值
        """
        if not self.jlJd or len(self.jlJd) < 16 or sv.Load(Year) is None or sv.Load(Year) != self.jlJd:
            _, jqbn = hq_24jieqi(year=Year)
            self.jlJd = []
            bnjq = None
            xnjq = None

            # 若生日时刻在立春之前，则取上年的节令
            lcjd = 0
            for _, jd in enumerate(jqbn):
                if jd[0] == '立春':
                    lcjd = jd[1]
                    break

            if self.srJd < lcjd:
                self.dnsr = False
                _, bnjq = hq_24jieqi(year=Year-1)
                xnjq = jqbn
            else:
                self.dnsr = True
                bnjq = jqbn
                _, xnjq = hq_24jieqi(year=Year+1, begin=1, total=6)

            for k, jq in enumerate(bnjq):
                if jq[0] in ('小寒', '立春', '惊蛰', '清明', '立夏', '芒种', '小暑', '立秋', '白露', '寒露', '立冬'):
                    self.jlJd = self.jlJd + [jq[1]]
                if jq[0] == '大雪' and k != 0:
                    self.jlJd = self.jlJd + [jq[1]]
            for k, jq in enumerate(xnjq):
                if jq[0] == '大雪' and k == 0:
                    self.jlJd = self.jlJd + [jq[1]]
                if jq[0] in ('小寒', '立春', '惊蛰', '清明'):
                    self.jlJd = self.jlJd + [jq[1]]

            sv.Dump(Year, self.jlJd)
        else:
            self.jlJd = sv.Load(Year)

        for i, J in enumerate(self.jlJd):
            if J >= self.srJd:
                return i - 1
        return 0

    # 取十神
    # by leuelcey (wyd)
    def hq_shishen(self, ri_gan=0, qt_gan=0):
        """
        取十神。
        用法：shen = hq_shishen([日干值][其他干值])
        :param ri_gan: 日干值
        :param qt_gan: 其他干值
        :return: 十神名
        """
        # 取天干的五行值
        def _hq_wuxing(gan=0):
            if gan % 2 != 0:
                gan -= 1
            return int(gan / 2)

        shen_key = (ri_gan + qt_gan) % 2
        name_idx = _hq_wuxing(qt_gan) - _hq_wuxing(ri_gan)
        if name_idx < 0:
            name_idx += 5

        key_name = list(self.shen.keys())[name_idx]
        return self.shen[key_name][shen_key]

    # 取本气
    # by leuelcey (wyd)
    def hq_benqi(self, gan=0, zhi=0):
        """
        取本气。
        :param gan: 天干值
        :param zhi: 地支值
        :return: 字典对象
        """
        sybiao = (
                (2, 3, 5, 6, 5, 6, 8, 9, 11, 0),
                (3, -1, 6, -1, 7, -1, 9, -1, 0, -1),
                (11, 11, 2, 2, 2, 2, 4, 4, 8, 8),
                (7, 7, 10, 10, 10, 4, 1, 1, 4, 4),
                (4, 4, 7, 7, -1, -1, 10, 10, 1, 1),
                (6, 6, 9, 9, 9, 9, 0, 0, 3, 3),
                (8, 8, 11, 11, 11, 11, 2, 2, 5, 5)
            )
        for i, dzz in enumerate(sybiao):
            if dzz[gan] == zhi:
                return {'zhi': i, 'benqi': self.benq[i]}
        return {'zhi': -1, 'benqi': '--'}

    # 取纳音
    # by leuelcey (wyd)
    def hq_nayin(self, gan=0, zhi=0):
        """
        取纳音。
        :param gan: 天干值
        :param zhi: 地支值
        :return: 纳音名
        """
        nayin = {0: {0: '海中金', 2: '大溪水', 4: '覆灯火', 6: '沙中金', 8: '井泉水', 10: '山头火'},
                 2: {0: '涧下水', 2: '炉中火', 4: '沙中土', 6: '天河水', 8: '山下火', 10: '屋上土'},
                 4: {0: '霹雳火', 2: '城头土', 4: '大林木', 6: '天上火', 8: '大驿土', 10: '平地木'},
                 6: {0: '壁上土', 2: '松柏木', 4: '白腊金', 6: '路旁土', 8: '石榴木', 10: '钗钏金'},
                 8: {0: '桑柘木', 2: '金箔金', 4: '长流水', 6: '杨柳木', 8: '剑锋金', 10: '大海水'}
        }
        if gan % 2 == 1:
            gan -= 1
            zhi -= 1
        return nayin[gan][zhi]

    # 取十二长生
    # by leuelcey (wyd)
    def hq_zhangsheng(self, gan=0, zhi=0):
        """
        取十二长生。
        :param gan: 天干值
        :param zhi: 地支值
        :return: 长生名
        """
        zswz = self.tgdz[gan]
        if gan % 2 == 0:
            zswz = zhi - zswz
        else:
            zswz = zswz - zhi
        if zswz < 0:
            zswz = zswz + 12
        return self.chsh[zswz]

    # 取命宫
    # by leuelcey (wyd)
    def hq_mingong(self, n_gan=0, y_zhi=0, s_zhi=0):
        """
        取命宫。
        :param n_gan: 年天干值
        :param y_zhi: 月地支值
        :param s_zhi: 时辰地支值
        :return: 命宫干支、名、纳音字典对象
        """
        mgdz = int((29 - y_zhi - s_zhi) % 12)
        xs = 1 if mgdz < 2 else 0
        mgtg = int(((n_gan % 5) * 2 + mgdz + 12 * xs) % 10)
        return {'ganzhi': (mgtg, mgdz), 'mingong': self.gans[mgtg] + self.zhis[mgdz], 'nayin': self.hq_nayin(mgtg, mgdz)}

    # 取胎元
    # by leuelcey (wyd)
    def hq_taiyuan(self, y_gan=0, y_zhi=0):
        """
        取胎元。
        :param y_gan: 月天干值
        :param y_zhi: 月地支值
        :return: 胎元干支、名、纳音字典对象
        """
        y_gan += 1
        if y_gan >= 10:
            y_gan = 0
        y_zhi += 3
        if y_zhi >= 12:
            y_zhi = 0
        return {'ganzhi': (y_gan, y_zhi), 'taiyuan': self.gans[y_gan] + self.zhis[y_zhi], 'nayin': self.hq_nayin(y_gan, y_zhi)}

    # 取星座
    # by leuelcey (wyd)
    def get_Zodiac(self, month=0, day=0):
        """
        取星座名。
        :param month: 西元月份
        :param day: 西元日
        :return: 星座名
        """
        sday = (22, 20, 19, 21, 20, 21, 22, 23, 23, 23, 24, 22)
        ixm = (month + 12) % 12
        if day < sday[ixm]:
            ixm = ((ixm + 12) - 1) % 12
        return self.zodiac[ixm]

    # 取五行
    def hq_wuxing(self):
        """
        根据命主四柱干支、藏干取其五行值。
        :return: 设置属性值
        """
        tg = self.gan_zhi['gan']
        wy, wn = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
        for ty in tg:
            ya, yn = 0, 0
            if ty % 2 == 0:
                ya = 1
            else:
                yn = 1
            ix = self.gwx[ty]
            wy[ix] = wy[ix] + ya
            wn[ix] = wn[ix] + yn
        for i in range(5):
            self.wuxing[0][i] = [wy[i], wn[i]]

        wy, wn = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
        dz = self.gan_zhi['zhi']
        for dy in dz:
            ya, yn = 0, 0
            if dy % 2 == 0:
                ya = 1
            else:
                yn = 1
            ix = self.zwx[dy]
            wy[ix] = wy[ix] + ya
            wn[ix] = wn[ix] + yn
        for i in range(5):
            self.wuxing[1][i] = [wy[i], wn[i]]
        
        wy, wn = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
        for i in range(4):
            cg = self.cangan[i]['cg']
            for g in cg:
                ya, yn = 0, 0
                if g % 2 == 0:
                    ya = 1
                else:
                    yn = 1
                ix = self.gwx[g]
                wy[ix] = wy[ix] + ya
                wn[ix] = wn[ix] + yn
        for i in range(5):
            self.wuxing[2][i] = [wy[i], wn[i]]

    # 八字排盘入口，提供命主性别，出生年、月、日、小时、分钟、秒、省份、区域
    # by leuelcey (wyd)
    @lru_cache
    def pai_bazi(self, *, Name='', Gender=0, Year=0, Month=0, Day=0, Hour=0, Minute=0, Second=0, Province='', Birthplace=''):
        """
        八字排盘入口程序。
        :param Name: 命主姓名
        :param Gender: 性别
        :param Year: 生日西元年
        :param Month: 生日西元月
        :param Day: 生日西元日
        :param Hour: 生日小时
        :param Minute: 生日分钟
        :param Second: 生日秒
        :param Province: 出生省份
        :param Birthplace: 出生地区
        :return: 设置各属性值
        """
        if Gender not in (0, 1) or Month < 0 or Month > 12 or Day < 0 or Day > 31 or Hour < 0 or Hour > 24 or Minute < 0 or Minute > 59 or Second < 0 or Second > 59 or not Province or not Birthplace:
            return None

        # ----------------------------------------------------------------------
        self.Owner = Name  # 命主
        self.Gender = Gender  # 性别
        self.Birthplace = Province + ' ' + Birthplace  # 出生地
        self.BornDay = (Year, Month, Day, Hour, Minute, Second)

        # -------------------经纬度、时区、生日儒略日-------------------------
        jwcode = bzbd.hq_jwcode(Province, Birthplace)  # 提取出生地经纬度代码
        csLng, csLat = lng_lat_decode(jwcode)  # 解码经纬度
        csTZ = -get_timezone(csLng)  # 出生地时区，占卜、算命、批八字时使用负值
        self.srJd = Gregory2Juday(Year, Month, Day + (Hour + Minute / 60 + Second / 3600) / 24)  # 取生日儒略日数

        self.Born_LNG = csLng  # 出生地经度
        self.Born_LAT = csLat  # 出生地维度

        # ---------------四柱、纳音、真及平太阳时、命宫、胎元----------------
        self.hq_sizhu(self.srJd + csTZ / 24 - J2000, csLng / radian)
        tg = self.gan_zhi['gan']
        dz = self.gan_zhi['zhi']

        self.Mean_Sun = mean_solar_time(Hour * 3600 + Minute * 60 + Second, csLng)  # 平太阳时
        self.kw_Base = self.hq_kw_Base(tg[2], dz[2])  # 日空亡基础数据
        self.mingong = self.hq_mingong(tg[0], dz[1], dz[3])  # 命宫
        self.taiyuan = self.hq_taiyuan(tg[1], dz[1])  # 胎元

        # -------------------大运干支、起运时间、起运数----------------------
        pans = 0  # 顺排或逆排时间跨度
        yuef = self.hq_jieling(Year=Year)  # 获取生年节令数组
        nfyy = tg[0] % 2  # 生年的阴阳
        dytg = []  # 暂存大运天干
        dydz = []  # 暂存大运地支
        # 性别为男、年份为阳或性别为女、年份为阴时，顺排
        if (Gender == 0 and nfyy == 0) or (Gender == 1 and nfyy == 1):
            pans = self.jlJd[yuef + 1] - self.srJd
            for i in range(1, 13):
                dytg = dytg + [(tg[1] + i) % 10]
                dydz = dydz + [(dz[1] + i) % 12]
        else:
            # 否则，性别为男、年份为阴或性别为女、年份为阳时，逆排
            pans = self.srJd - self.jlJd[yuef]
            for i in range(1, 13):
                dytg = dytg + [(tg[1] + 20 - i) % 10]
                dydz = dydz + [(dz[1] + 24 - i) % 12]
        jlts = int(pans * 4 * 30)

        self.qiyun = f'{int(jlts / 360)}年{int(jlts % 360 / 30)}月{int(jlts % 360 % 30)}天起运'  # 开始起运时刻
        self.qy_Time = Juday2Gregory(self.srJd + pans * 4 * 30)  # 起运时间
        self.qy_sui = [f'{str(x)}岁' for x in range(self.qy_Time[0] - Year, 100, 10)]  # 行运岁数

        # -----------------------十神、空亡、藏干、本气-----------------------
        self.cangan = []  # 人元：即地支藏干
        self.shishen = []  # 十神
        self.benqi = []  # 本气
        self.kongwang = []  # 空亡
        for i in range(4):
            self.shishen = self.shishen + [self.hq_shishen(tg[2], tg[i])]
            self.kongwang = self.kongwang + [self.hq_kongwang(dz[i])]

            dzcg = self.cgan[dz[i]]  # 取该地支的藏干数组
            cgsh = []  # 暂存所藏天干的对应十神
            cgtg = []  # 暂存藏干的天干名
            for cg in dzcg:
                cgsh = cgsh + [self.hq_shishen(tg[2], cg)]
                cgtg = cgtg + [self.gans[cg]]
            self.cangan = self.cangan + [{'cg': dzcg, 'gan': cgtg, 'shishen': cgsh}]
            self.benqi = self.benqi + [self.hq_benqi(tg[2], dz[i])]
        self.shishen[2] = '日元'  # 日十神固定为`日元`或`元`或`日`
        if self.kongwang[2] != self.kw_Base['kongwang']:
            self.kongwang[2] = self.kw_Base['kongwang']

        # ---------------------长生、生肖、星座--------------------------------
        self.zhangsheng = []  # 十二长生
        n_zs, y_zs, r_zs, s_zs = [], [], [], []
        for i in range(4):
            n_zs = n_zs + [self.hq_zhangsheng(tg[0], dz[i])]
            y_zs = y_zs + [self.hq_zhangsheng(tg[1], dz[i])]
            r_zs = r_zs + [self.hq_zhangsheng(tg[2], dz[i])]
            s_zs = s_zs + [self.hq_zhangsheng(tg[3], dz[i])]
        self.zhangsheng = self.zhangsheng + [n_zs] + [y_zs] + [r_zs] + [s_zs]
        self.shengxiao = self.xiao[dz[0]]  # 生肖
        self.Zodiac = self.get_Zodiac(Month, Day)  # 星座

        # ----------------------------------大运--------------------------------
        self.dy_gan = dytg  # 大运天干
        self.dy_zhi = dydz  # 大运地支
        self.dayun_gz = []  # 各步运的干支名
        self.dayun_sj = []  # 各步运的起始时间
        self.dayun_10 = []  # 各步运的十神
        self.dayun_zs = []  # 各步运的长生
        for i in range(12):
            self.dayun_gz = self.dayun_gz + [self.gans[dytg[i]] + self.zhis[dydz[i]]]
            self.dayun_sj = self.dayun_sj + [Juday2Gregory(self.srJd + pans * 120 + i * 10 * 365)]
            self.dayun_zs = self.dayun_zs + [self.hq_zhangsheng(tg[2], dydz[i])]
            self.dayun_10 = self.dayun_10 + [self.hq_shishen(tg[2], dytg[i])]

        # ----------------------------------流年--------------------------------
        self.liunian = []
        i = n = 0 if self.dnsr else 1
        for j in range(121):
            lng = (tg[0] + i) % 10
            lnz = (dz[0] + i) % 12
        
            ncg = self.cgan[lnz]
            n10 = ''
            cgm = ''
            for cg in ncg:
                n10 = n10 + (' ' if n10 else '') + self.hq_shishen(tg[2], cg)
                cgm = cgm + (' ' if cgm else '') + self.gans[cg]

            lnxx = {
                        'nian': Year + i - n,
                        'ganzhi': (lng, lnz),
                        'nian_gz': self.gans[lng] + self.zhis[lnz],
                        'cangan': ncg,
                        'cg_ming': cgm,
                        'nian_zs': self.hq_zhangsheng(tg[2], lnz),
                        'nian_10': self.hq_shishen(tg[2], lng),
                        'n_cg_10': n10
            }
            self.liunian = self.liunian + [lnxx]
            i += 1

        # ----------------------------------星煞--------------------------------
        xsha = Xingsha(
                            gan=self.gan_zhi['gan'],
                            zhi=self.gan_zhi['zhi'],
                            nayin=self.nayin,
                            gender=self.Gender
            )
        xingsha = xsha.xs_Funcs_Run()
        self.xing_sha = xingsha
        # 取五行，天元、地元、人元
        self.wuxing = [
            [[], [], [], [], []],
            [[], [], [], [], []],
            [[], [], [], [], []]
        ]
        self.hq_wuxing()
        # 计算相应的信息
        self.xysr.month_calendar(Year, Month)
        # 计算完毕标志
        self.flag = True

    # 命令行显示排盘结果
    # by leuelcey (wyd)
    def pai_pan(self):
        """
        显示排盘结果(命令行模式下)。
        :return: 只显示
        """
        if not self.flag:
            return

        # 按显示格式获取藏干信息
        def _hq_cg():
            cg = {}
            for xx in self.cangan:
                for k, g in enumerate(xx['gan']):
                    ks = f'h{k}'
                    if ks not in cg:
                        cg[ks] = []
                    gs = g + ' ' + xx['shishen'][k]
                    hx = f'{gs}'.center(11-len(gs))
                    cg[ks] = cg[ks] + [hx]
            for x in cg:
                if len(cg[x]) < 4:
                    for i in range(4 - len(cg[x])):
                        cg[x].append(' ' * 10)
            return cg
        # 按显示格式获取长生信息
        def _hq_zs():
            zs = [[], []]
            for i in range(4):
                uz = self.zhangsheng[i][0] + ' ' + self.zhangsheng[i][1]
                dz = self.zhangsheng[i][2] + ' ' + self.zhangsheng[i][3]
                us = f'{uz}'.center(11-len(uz))
                ds = f'{dz}'.center(11-len(dz))
                zs[0] = zs[0] + [us]
                zs[1] = zs[1] + [ds]
            return zs

        scjd = Gregory2Juday(datetime.now().year, datetime.now().month, datetime.now().day) - self.srJd
        scns = scjd / 365.25
        scys = (scns - floor(scns)) * 365.25 / 30
        scts = (scys - floor(scys)) * 30 + (1 if scys - floor(scys) > 0 else 0)

        srxx = self.xysr.datas_convert(HasMonth=False, BeginDay=self.BornDay[2], Days=1)['Daily'][0]
        nian = srxx['nian1']
        nsui = f'{floor(scns)}岁 {floor(scys)}月 {floor(scts)}天'
        scrq = f'{self.BornDay[0]}-' + (f'{self.BornDay[1]}-' if self.BornDay[1] > 9 else f'0{self.BornDay[1]}-') + (f'{self.BornDay[2]}' if self.BornDay[2] > 9 else f'0{self.BornDay[2]}')
        scsj = (f'{self.BornDay[3]}:' if self.BornDay[3] > 9 else f'0{self.BornDay[3]}:') + (f'{self.BornDay[4]}:' if self.BornDay[4] > 9 else f'0{self.BornDay[4]}:') + (f'{self.BornDay[5]}' if self.BornDay[5] > 9 else f'0{self.BornDay[5]}')
        nlsc = '农历 ' + hq_nl_nian(nian) + '年 ' + srxx['yue_ming'] + '月 ' + srxx['ri_ming'] + '日 ' + self.sizhu[3][1] + '时'

        print()
        print('命主：' + self.Owner.ljust(14-len(self.Owner)) + '性别：' + ('男' if self.Gender == 0 else '女').ljust(5) + '年龄：' + nsui)
        print('生辰：' + f'西元 {scrq} {scsj} ' + get_Week(srxx['Week']))
        print('           ' + f'{scrq} {self.Real_Sun} (真太阳时)')
        print('           ' + f'{scrq} {self.Mean_Sun} (平太阳时)')
        print('      ' + f'{nlsc}')
        print('生日时辰：' + self.shichen)
        print('生肖：' + self.shengxiao.ljust(14-len(self.shengxiao)) + '星座：' + self.Zodiac)
        print('出生地：' + self.Birthplace)
        print('        经度：' + f'{self.Born_LNG}'.rjust(11))
        print('        维度：' + f'{self.Born_LAT}'.rjust(11))
        print()
        print(('乾' if self.Gender == 0 else '坤') + '造：   ', end='')
        print(self.shishen[0].center(10-len(self.shishen[0])) + self.shishen[1].center(10-len(self.shishen[1])) + self.shishen[2].center(10-len(self.shishen[2])) + self.shishen[3].center(10-len(self.shishen[3])) + '    ' + ' 命宫   胎元')
        print('          ---------+---------+---------+--------     ------+------')
        print('         ' + self.sizhu[0][0].center(10-len(self.sizhu[0][0])) + self.sizhu[1][0].center(10-len(self.sizhu[1][0])) + self.sizhu[2][0].center(10-len(self.sizhu[2][0])) + self.sizhu[3][0].center(10-len(self.sizhu[3][0])), end='')
        print('    ' + self.mingong['mingong'][0].center(7-len(self.mingong['mingong'][0])) + self.taiyuan['taiyuan'][0].center(7-len(self.taiyuan['taiyuan'][0])))
        print('         ' + self.sizhu[0][1].center(10-len(self.sizhu[0][1])) + self.sizhu[1][1].center(10-len(self.sizhu[1][1])) + self.sizhu[2][1].center(10-len(self.sizhu[2][1])) + self.sizhu[3][1].center(10-len(self.sizhu[3][1])), end='')
        print('    ' + self.mingong['mingong'][1].center(7-len(self.mingong['mingong'][1])) + self.taiyuan['taiyuan'][1].center(7-len(self.taiyuan['taiyuan'][1])))
        print('          ---------+---------+---------+--------' + '     ' + self.mingong['nayin'].center(7-len(self.mingong['nayin'])) + self.taiyuan['nayin'].center(7-len(self.taiyuan['nayin'])))
        print('空亡：   ' + self.kongwang[0].center(10-len(self.kongwang[0])) + self.kongwang[1].center(10-len(self.kongwang[1])) + self.kongwang[2].center(10-len(self.kongwang[2])) + self.kongwang[3].center(10-len(self.kongwang[3])))
        print('          ---------+---------+---------+--------')
        cg = _hq_cg()
        for i in range(len(cg)):
            if i == 0:
                print('藏干：   ', end='')
            else:
                print('         ', end='')
            ks = f'h{i}'
            print(cg[ks][0] + cg[ks][1] + cg[ks][2] + cg[ks][3])
        print('          ---------+---------+---------+--------')
        zs = _hq_zs()
        print('长生：   ' + zs[0][0] + zs[0][1] + zs[0][2] + zs[0][3])
        print('         ' + zs[1][0] + zs[1][1] + zs[1][2] + zs[1][3])
        print('          ---------+---------+---------+--------')
        print('纳音：   ' + self.nayin[0].center(10-len(self.nayin[0])) + self.nayin[1].center(10-len(self.nayin[1])) + self.nayin[2].center(10-len(self.nayin[2])) + self.nayin[3].center(10-len(self.nayin[3])))
        print('\n星煞：')
        print('    [年] ' + ' '.join(self.xing_sha[0]))
        print('    [月] ' + ' '.join(self.xing_sha[1]))
        print('    [日] ' + ' '.join(self.xing_sha[2]))
        print('    [时] ' + ' '.join(self.xing_sha[3]))
        print()
        print('五行：      木        火        土        金        水')
        print('          阳  阴    阳  阴    阳  阴    阳  阴    阳  阴')
        print('  [天元]  ', end='')
        for i in range(5):
            wy = (' ' if self.wuxing[0][i][0] < 10 else '') + f'{self.wuxing[0][i][0]}'
            wn = (' ' if self.wuxing[0][i][1] < 10 else '') + f'{self.wuxing[0][i][1]}'
            print(f'{wy}, {wn}'.center(6), end='')
            print('    ', end='')
        print('\n  [地元]  ', end='')
        for i in range(5):
            wy = (' ' if self.wuxing[1][i][0] < 10 else '') + f'{self.wuxing[1][i][0]}'
            wn = (' ' if self.wuxing[1][i][1] < 10 else '') + f'{self.wuxing[1][i][1]}'
            print(f'{wy}, {wn}'.center(6), end='')
            print('    ', end='')
        print('\n  [人元]  ', end='')
        for i in range(5):
            wy = (' ' if self.wuxing[2][i][0] < 10 else '') + f'{self.wuxing[2][i][0]}'
            wn = (' ' if self.wuxing[2][i][1] < 10 else '') + f'{self.wuxing[2][i][1]}'
            print(f'{wy}, {wn}'.center(6), end='')
            print('    ', end='')
        ya, yn = [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]
        for i in range(5):
            ya[i] = ya[i] + self.wuxing[0][i][0] + self.wuxing[1][i][0] + self.wuxing[2][i][0]
            yn[i] = yn[i] + self.wuxing[0][i][1] + self.wuxing[1][i][1] + self.wuxing[2][i][1]
        print('\n          ', end='')
        for i in range(5):
            wy = (' ' if ya[i] < 10 else '') + f'{ya[i]}'
            wn = (' ' if yn[i] < 10 else '') + f'{yn[i]}'
            print(f'{wy}, {wn}'.center(6), end='')
            print('    ', end='')
        print()
        print('\n起运时刻：' + self.qiyun)
        print('起运时间：' + f'{self.qy_Time[0]}年{self.qy_Time[1]}月{self.qy_Time[2]}日 {self.qy_Time[3]}时{self.qy_Time[4]}分{round(self.qy_Time[5])}秒')
        print()
        print('大运：   ' + '  '.join(self.dayun_gz[:10]))
        print('         ' + '  '.join(self.dayun_10[:10]) + ' (十神)')
        print('        ', end='')
        for zs in self.dayun_zs[:10]:
            print(zs.center(6-len(zs)), end='')
        print('(长生)')
        print('行运岁数：' + '  '.join(self.qy_sui))
        print()

        nfbt = '            '.join([f'{nf[0]}' for _, nf in enumerate(self.dayun_sj[:5])])
        qsxh = 0
        for k, ln in enumerate(self.liunian):
            if ln['nian'] == self.qy_Time[0]:
                qsxh = k
                break
        print('起于：' + f'{nian}'.ljust(6) + nfbt)
        for i in range(11):
            ks = qsxh + i
            if i == 0:
                print('流年：      ', end='')
            else:
                print('            ', end='')
            for j in range(ks, ks + 50, 10):
                lnxx = self.liunian[j]['nian_gz'] + ' ' + self.liunian[j]['nian_zs'] + ',' + self.liunian[j]['nian_10']
                print(lnxx.ljust(16-len(lnxx)+2), end='')
            print()
        nfbw = '            '.join([f'{nf[0]+10}' for _, nf in enumerate(self.dayun_sj[:5])])
        print('            ' + nfbw)
        
        print()
        nfbt = '            '.join([f'{nf[0]}' for _, nf in enumerate(self.dayun_sj[5:10])])
        print('            ' + nfbt)
        qsxh += 50
        for i in range(11):
            ks = qsxh + i
            if i == 0:
                print('流年：      ', end='')
            else:
                print('            ', end='')
            for j in range(ks, ks + 50, 10):
                lnxx = self.liunian[j]['nian_gz'] + ' ' + self.liunian[j]['nian_zs'] + ',' + self.liunian[j]['nian_10']
                print(lnxx.ljust(16 - len(lnxx) + 2), end='')
            print()
        nfbw = '            '.join([f'{nf[0]+10}' for _, nf in enumerate(self.dayun_sj[5:10])])
        print('            ' + nfbw)
        print()

        gua = self.bgua.qg_lianshan(
                qglx=0,
                nian=self.sizhu[0],
                yue=srxx['yue_ming'],
                ri=srxx['ri_ming'],
                shi=self.sizhu[3]
        )
        if gua:
            print('本卦：' + gua['ben_gua']['gua_ci']['xu'] + ' ' + gua['ben_gua']['gua_ci']['ming'] + ' ' + gua['ben_gua']['gua_ci']['jue'])
            print('        ' + gua['ben_gua']['mings'][0] + '上 ' + gua['ben_gua']['xings'][0])
            print('        ' + gua['ben_gua']['mings'][1] + '下 ' + gua['ben_gua']['xings'][1])
            print()
            print('        ' + gua['ben_gua']['gua_ci']['wen'])
            print('        ' + gua['ben_gua']['gua_ci']['tuan'])
            print('        ' + gua['ben_gua']['gua_ci']['xiang'])
            print()
            print('        ' + gua['ben_gua']['yao_ci']['wen'])
            print('        ' + gua['ben_gua']['yao_ci']['xiang'])
            print()
            print('变卦：' + gua['bian_gua']['gua_ci']['xu'] + ' ' + gua['bian_gua']['gua_ci']['ming'] + ' ' + gua['bian_gua']['gua_ci']['jue'])
            print('        ' + gua['bian_gua']['mings'][0] + '上 ' + gua['bian_gua']['xings'][0])
            print('        ' + gua['bian_gua']['mings'][1] + '下 ' + gua['bian_gua']['xings'][1])
            print()
            print('        ' + gua['bian_gua']['gua_ci']['wen'])
            print('        ' + gua['bian_gua']['gua_ci']['tuan'])
            print('        ' + gua['bian_gua']['gua_ci']['xiang'])
            print()
            print('        ' + gua['bian_gua']['yao_ci']['wen'])
            print('        ' + gua['bian_gua']['yao_ci']['xiang'])
            print()

    # 命令行程序入口
    # by leuelcey (wyd)
    def start(self, custom=False):
        """
        命令行模式下程序入口。
        :param custom: 为`True`时输入命主信息；为`False`时使用当前时间作为命主生辰
        :return: 无，结束后可使用`pai_pan`显示结果
        """
        name = input('                                      姓名（可空）：')
        gender = int(input('                                性别（0:男，1:女）：'))
        if custom:
            dY = int(input('      年份（前4712～9999年有效，西元前加 B、b或-）：'))
            dM = int(input('                                 出生月份（1～12）：'))
            dD = int(input('                                   出生日（1～31）：'))
            dh = int(input('                                  出生小时（24制）：'))
            dm = int(input('                                 出生分钟（0～59）：'))
            ds = int(input('                                   出生秒（0～59）：'))
        else:
            cnow = datetime.now()
            dY = cnow.year
            dM = cnow.month
            dD = cnow.day
            dh = cnow.hour
            dm = cnow.minute
            ds = cnow.second

        sheng = input('                                          出生省份：')
        chsdi = input('                                            出生地：')

        self.flag = False
        self.pai_bazi(Name=name, Gender=gender, 
                        Year=dY, Month=dM, Day=dD,
                        Hour=dh, Minute=dm, Second=ds,
                        Province=sheng, Birthplace=chsdi
                      )


# 星煞类
# 实例化时需要传入 Bazi 类计算后的四柱的天干值列表、地支值列表、纳音，性别
class Xingsha(object):
    """
    星煞类。
    """
    __slots__ = ('__dict__', '__weakref__', 'tg', 'dz', 'nayin', 'gender', 'xing_sha', 'xsha', 'nywx')

    def __init__(self, gan, zhi, nayin, gender):
        super(Xingsha, self).__init__()
        self.tg = gan
        self.dz = zhi
        self.nayin = nayin
        self.gender = gender
        self.xing_sha = None
        self.xsha = bzbd.get_constant(section='bazi', varname='xing_sha')  # 星煞
        self.nywx = bzbd.get_constant(section='bazi', varname='nywx')  # 纳音对应五行

    # 0空亡
    # 甲子旬中戌亥空，甲戌旬中申酉空，甲申旬中午未空。
    # 甲午旬中辰巳空，甲辰旬中寅卯空，甲寅旬中子丑空。
    # 在八字类中已定义

    # 1天乙贵人
    # 甲戊并牛羊，乙己鼠猴乡
    # 丙丁猪鸡位，壬癸兔蛇藏
    # 庚辛逢虎马，此是贵人方
    # 以年干查的贵人为大贵人、以日干查的贵人为小贵人
    # 2太极贵人
    # 甲乙生人子午中，丙丁鸡兔定亨通;
    # 戊己两干临四季，庚辛寅亥禄丰隆;
    # 壬癸巳申偏喜美，值此应当福气钟;
    # 以年干或日干为准，四柱地支见者为是
    def xs_Many_01(self, xsming=''):
        g0 = self.tg[0]
        g2 = self.tg[2]
        if xsming == '天乙':
            dy = {0: (1, 7), 1: (0, 8), 2: (9, 11), 3: (9, 11), 4: (1, 7), 5: (0, 8), 6: (6, 2), 7: (6, 2), 8: (3, 5), 9: (3, 5)}
        if xsming == '太极':
            dy = {0: (0, 6), 1: (0, 6), 2: (3, 9), 3: (3, 9), 4: (4, 10, 1, 7), 5: (4, 10, 1, 7), 6: (2, 11), 7: (2, 11), 8: (5, 7), 9: (5, 7)}
        ty = dy[g0] + dy[g2]
        for i in range(4):
            if self.dz[i] in ty:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 3天医
    # 正月生见丑，二月生见寅，三月生见卯，四月生见辰，
    # 五月生见巳，六月生见午，七月生见未，八月生见申，
    # 九月生见酉，十月生见戌，冬月生见亥，腊月生见子。
    # 以月支查其它地支，见者为是
    def xs_tianyi1(self, xsming=''):
        ty = (self.dz[1] + 12 - 1) % 12
        for i in range(4):
            if i == 1:
                continue
            if ty == self.dz[i]:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 4天德
    # 正月2生者见丁3，二月3生者见申8，三月4生者见壬8，四月生者见辛，
    # 五月生者见亥，六月生者见甲，七月生者见癸，八月生者见寅，
    # 九月生者见丙，十月生者见乙，冬月0生者见巳，腊月1生者见庚。
    def xs_tiande(self, xsming=''):
        dy = {0: (1, 5), 1: (0, 6), 2: (0, 3), 3: (1, 8), 4: (0, 8), 5: (0, 7), 6: (1, 11), 7: (0, 0), 8: (0, 9), 9: (1, 2), 10: (0, 2), 11: (0, 1)}
        jg = dy[self.dz[1]]
        if jg[0] == 0:
            td = self.tg
        else:
            td = self.dz
        for i in range(4):
            if td[i]  == jg[1]:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 5月德
    # 寅午戌月生者见丙2，申子辰月生者见壬8，亥卯未月生者见甲0，巳酉丑月生者见庚6。
    def xs_yuede(self, xsming=''):
        dy = (8, 6, 2, 0, 8, 6, 2, 0, 8, 6, 2, 0)
        yd = dy[self.dz[1]]
        for i in range(4):
            if yd == self.tg[i]:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]
    
    # 6禄神
    # 甲禄在寅，乙禄在卯， 丙戊禄在巳，丁己禄在午，
    # 庚禄在申, 辛禄在酉，壬禄在亥，癸禄在子。以日查4枝
    def xs_lushen(self, xsming=''):
        dy = (2, 3, 5, 6, 5, 6, 8, 9, 11, 0)
        ls = dy[self.tg[2]]
        for i in range(4):
            if ls == self.dz[i]:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 7羊刃
    # 以日干:甲木见卯为羊刃;丙火、戊土见午为羊刃;
    # 庚金见酉为羊刃;壬水见子为羊刃,阴干没有羊刃
    def xs_yangren(self, xsming=''):
        dy = {0: 3, 2: 6, 4: 6, 6: 9, 8: 0}
        if self.tg[2] in dy:
            yr = dy[self.tg[2]]
            for i in range(4):
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 8孤鸾
    # 日柱和时柱上只要同时出现以下干支组合中的任何两组，就会“命犯孤鸾”：
    # 乙巳、丁巳、辛亥、戊申、甲寅、戊午、壬子、丙午。
    def xs_guluan(self, xsming=''):
        dy = ('1-5', '3-5', '7-11', '4-8', '0-2', '4-6', '8-0', '2-6')
        dd = str(self.tg[2]) + '-' + str(self.dz[2])
        hh = str(self.tg[2]) + '-' + str(self.dz[3])
        if dd in dy and hh in dy:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 9三奇
    # 三奇贵人,即奇门遁甲里的三奇
    # 天上三奇甲戊庚;地上三奇乙丙丁;人中三奇壬癸辛。
    # 三奇不管顺逆，只要连续三个天干相连，即可入格，重逢更贵。
    def xs_sanqi(self, xsming=''):
        zg = [str(g) for g in self.tg]
        sg = '-'.join(zg)
        dy = ('0-4-6', '6-4-0', '1-2-3', '3-2-1', '8-9-6', '6-9-8')
        for _, d in enumerate(dy):
            v = sg.find(d)
            if v < 0:
                continue
            if v == 2:
                self.xing_sha[3] = self.xing_sha[3] + [xsming]
            else:
                self.xing_sha[0] = self.xing_sha[0] + [xsming]
            self.xing_sha[1] = self.xing_sha[1] + [xsming]
            self.xing_sha[2] = self.xing_sha[2] + [xsming]
            break

    # 10天赦
    # 寅卯辰月见戊寅日；巳午未月见甲午日；申酉戌月见戊申日；
    # 亥子丑月见甲子日，都是天赦。
    def xs_tianshe(self, xsming=''):
        if self.dz[1] in (2, 3, 4) and self.tg[2] == 4 and self.dz[2] == 2:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]
        if self.dz[1] in (5, 6, 7) and self.tg[2] == 0 and self.dz[2] == 6:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]
        if self.dz[1] in (8, 9, 10) and self.tg[2] == 4 and self.dz[2] == 8:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]
        if self.dz[1] in (11, 0, 1) and self.tg[2] == 0 and self.dz[2] == 0:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 11德秀
    # 在寅月、午月、戌月出生的人，如果八字中天干见戊癸合，另外四柱中再有丙、丁其中之一者，为德秀贵人。
    # 在申月、子月、辰月出生的人，如果八字中天干见丙辛合、甲己合，另外四柱中再有壬、癸、戊、己其中之一者，为德秀贵人。
    # 在巳月、酉月、丑月出生的人，如果八字中天干有乙庚合，另外四柱中再有庚、辛其中之一者，为德秀贵人。
    # 在亥月、卯月、未月出生的人，如果八字中天干有丁壬合，另外四柱中再有甲、乙其中之一者，为德秀贵人。
    # 都是三合局的月
    def xs_dexiu(self, xsming=''):
        dx = []
        if self.dz[1] in (2, 6, 10) and 2 in self.tg and 3 in self.tg:
            dx = get_keys(self.tg, 2) + get_keys(self.tg, 3)
        if self.dz[1] in (8, 0, 4) and ((2 in self.tg and 7 in self.tg) or (0 in self.tg and 5 in self.tg)):
            dx = get_keys(self.tg, 8) + get_keys(self.tg, 9) + get_keys(self.tg, 4) + get_keys(self.tg, 5)
        if self.dz[1] in (5, 9, 1) and 1 in self.tg and 6 in self.tg:
            dx = get_keys(self.tg, 6)
            del dx[0]
            dx = dx + get_keys(self.tg, 7)
        if self.dz[1] in (11, 3, 7) and 3 in self.tg and 8 in self.tg:
            dx = get_keys(self.tg, 0) + get_keys(self.tg, 1)

        if dx:
            for i in dx:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 12魁罡
    # 壬辰，庚戍，庚辰，戊戍。日柱是这四组的话，就是命带魁罡
    def xs_kuigang(self, xsming=''):
        dy = ('8-4', '7-10', '7-4', '4-10')
        kg = str(self.tg[2]) + '-' + str(self.dz[2])
        if kg in dy:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 13金神
    # 算法1:日柱是乙丑日、己巳日、癸酉日,月支有火星者方眞。否则须运逢火地才能富贵。
    # 算法2:时是乙丑时、己巳时、癸酉时,但必需日干甲或者己方是,否则非。又须月支见火星方眞, 否则须运逢火鄕方能富贵。
    def xs_jinshen(self, xsming=''):
        dy = ('1-1', '5-5', '8-8')
        ho = (2, 5, 6, 7, 10)
        js = str(self.tg[2]) + '-' + str(self.dz[2])
        if js in dy:
            if self.dz[1] in ho:
                xsming = xsming + '(带火)'
            else:
                xsming = xsming + '(无火)'
            self.xing_sha[2] = self.xing_sha[2] + [xsming]
        if self.tg[2] in (0, 1):
            sj = str(self.tg[3]) + '-' + str(self.dz[3])
            if sj in dy:
                if self.dz[1] in ho:
                    xsming = xsming + '(带火)'
                else:
                    xsming = xsming + '(无火)'
            self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 14天罗
    # 年柱为戊子、己丑、丙寅、丁卯、甲辰、乙巳、戊午、己未、丙申、丁酉、甲戌、乙亥(纳音为火)的八字，
    # 而日支中又出现了戌或亥为天罗
    # 15地网
    # 年柱为丙子、丁丑、甲寅、乙卯、壬辰、癸巳、丙午、丁未、甲申、乙酉、壬戌、癸亥；
    # 庚子、辛丑、戊寅、己卯、丙辰、丁巳、庚午、辛未、戊申、己酉、丙戌、丁亥的八字，
    # 在日支当中又出现了辰或巳为地网
    def xs_Many_02(self, xsming=''):
        if xsming == '天罗':
            dy = ('4-0', '5-1', '2-2', '3-3', '0-4', '1-5', '4-6', '5-7', '2-8', '3-9', '0-10', '1-11')
            sy = (10, 11)
        if xsming == '地网':
            dy = ('2-0','4-1','0-2','1-3','8-4','9-5','2-6','3-7','0-8','1-9','8-10','9-11',
                '6-0','7-1','4-2','5-3','2-4','3-5','7-6','8-7','4-8','5-9','2-10','3-11')
            sy = (4, 5)
        if self.dz[2] in sy:
            jg = str(self.tg[0]) + '-' + str(self.dz[0])
            if jg in dy:
                self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 16文昌
    # 日干或者年干为甲，地支见巳者；
    # 日干或年干为乙，地支见午者；
    # 日干或年干为为丙，地支见申者；
    # 日干或年干为丁，地支见酉者；
    # 日干或年干为戊，地支见申者；
    # 日干或年干为己，地支见酉者；
    # 日干或年干为庚，地支见亥者；
    # 日干或年干为辛，地支见子者；
    # 日干或年干为壬，地支见寅者；
    # 日干或年干为癸，地支见卯者。
    # 以上皆为文昌贵人
    def xs_wenchang(self, xsming=''):
        wc = -1
        if self.tg[2] == 0 or self.tg[0] == 0:
            wc = 5
        if self.tg[2] == 1 or self.tg[0] == 1:
            wc = 6
        if self.tg[2] == 2 or self.tg[0] == 2:
            wc = 8
        if self.tg[2] == 3 or self.tg[0] == 3:
            wc = 9
        if self.tg[2] == 4 or self.tg[0] == 4:
            wc = 8
        if self.tg[2] == 5 or self.tg[0] == 5:
            wc = 9
        if self.tg[2] == 6 or self.tg[0] == 6:
            wc = 11
        if self.tg[2] == 7 or self.tg[0] == 7:
            wc = 0
        if self.tg[2] == 8 or self.tg[0] == 8:
            wc = 2
        if self.tg[2] == 9 or self.tg[0] == 9:
            wc = 3
        if wc >= 0:
            for i in range(4):
                if self.dz[i] == wc:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 17金舆
    # 甲龙乙蛇丙戊羊，丁己猴歌庚犬方，辛猪壬牛癸逢虎，凡人遇此福气昌,
    # 以日干为主，四支见者为是。
    def xs_jinyu(self, xsming=''):
        dy = {0:4, 1:5, 2:7, 3:8, 4:7, 5:8, 6:10, 7:11, 8:1, 9:2}
        jg = self.tg[2]
        if jg in dy:
            jy = dy[jg]
            for i in range(4):
                if self.dz[i] == jy:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 18福星
    # 凡甲、丙两干见寅或子，乙、癸两干见卯或丑，戊干见申，己干见未，丁干见亥，庚干见午，辛干见巳，壬干见辰是也。年或日
    def xs_fuxing(self, xsming=''):
        fx = []
        if self.tg[2] in (0, 2) or self.tg[0] in (0, 2):
            fx = [0, 2]
        if self.tg[2] in (1, 9) or self.tg[0] in (1, 9):
            fx = [3, 1]
        if self.tg[2] == 4 or self.tg[0] == 4:
            fx = [8]
        if self.tg[2] == 5 or self.tg[0] == 5:
            fx = [7]
        if self.tg[2] == 3 or self.tg[0] == 3:
            fx = [11]
        if self.tg[2] == 6 or self.tg[0] == 6:
            fx = [6]
        if self.tg[2] == 7 or self.tg[0] == 7:
            fx = [5]
        if self.tg[2] == 8 or self.tg[0] == 8:
            fx = [4]
        if fx:
            for i in range(4):
                if self.dz[i] in fx:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 19国印
    # 甲见戌，乙见亥，丙见丑，丁见寅，戊见丑，己见寅，庚见辰，辛见巳，壬见未，癸见申。以年干或日干为主, 地支见者为是
    # 20天厨
    # 凡甲干见巳，乙干见午，丙干见子，丁干见已，戊干见午，己干见申，庚干见寅，辛干见午，壬干见酉，癸干见亥。
    def xs_Many_03(self, xsming=''):
        if xsming == '国印':
            dy = {0:10, 1:11, 2:1, 3:2, 4:1, 5:2, 6:4, 7:5, 8:7, 9:8}
        if xsming == '天厨':
            dy = {0:5, 1:6, 2:0, 3:5, 4:6, 5:8, 6:2, 7:6, 8:9, 9:11}
        gy = []
        if self.tg[0] in dy:
            gy = gy + [dy[self.tg[0]]]
        if self.tg[2] in dy:
            gy = gy + [dy[self.tg[2]]]
        if gy:
            for i in range(4):
                if self.dz[i] in gy:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 21学堂
    # 年纳音为木，月日时支见亥；
    # 年纳音为火，月日时支见寅；
    # 年纳音为土，月日时支见申；
    # 年纳音为金，月日时支见巳；
    # 年纳音为水，月日时支见申。
    def xs_xuetang(self, xsming=''):
        dy = {0:11, 1:2, 2:8, 3:5, 4:8}
        wx = -1
        ny = self.nayin[0]
        if ny in self.nywx:
            wx = self.nywx[ny][0]
        if wx in dy:
            xt = dy[wx]
            for i in range(4):
                if i == 0:
                    continue
                if self.dz[i] == xt:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 22红艳
    # 日天干是甲，地支见午；
    # 日天干是乙，地支见申；
    # 日天干是丙，地支见寅；
    # 日天干是丁，地支见未；
    # 日天干是戊，地支见辰；
    # 日天干是己，地支见辰；
    # 日天干是庚，地支见戌；
    # 日天干是辛，地支见酉；
    # 日天干是壬，地支见子；
    # 日天干是癸，地支见申。
    # 23流霞
    # 甲日酉、乙日戌、丙日未、丁日申、戊日巳；己日午、庚日辰、辛日卯、壬日亥、癸日寅
    def xs_Many_04(self, xsming=''):
        if xsming == '红艳':
            dy = {0:6, 1:8, 2:2, 3:7, 4:4, 5:4, 6:10, 7:9, 8:0, 9:8}
        if xsming == '流霞':
            dy = {0:9, 1:10, 2:7, 3:8, 4:5, 5:6, 6:4, 7:3, 8:11, 9:2}
        sy = self.tg[2]
        if sy in dy:
            hy = dy[sy]
            for i in range(4):
                if self.dz[i] == hy:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 24将星，三合局里的中间。寅午戌见午，申子辰见子，巳酉丑见酉，亥卯未见卯，只有3,6,9
    # 25华盖，三合局里最后一个。寅午戌 申子辰 巳酉丑 亥卯未
    # 26驿马，申子辰马在寅，寅午戌马在申，巳酉丑马在亥，亥卯未马在巳。
    # 27劫煞，克三合局的属性，以年支或日支为主，其他地支见者为是。申子辰见巳，亥卯未见申，寅午戌见亥，巳酉丑见寅。
    # 28亡神，申子辰以11，寅午戌以5，巳酉丑以8，亥卯未以2
    # 40桃花，即子午卯酉这4个正向(北,南,东,西)，亥卯未见子0、巳酉丑见午6、寅午戌见卯3、申子辰见酉9
    def xs_Many_05(self, xsming=''):
        yy = self.dz[0]
        dd = self.dz[2]
        if xsming == '将星':
            dy = (0, 9, 6, 3, 0, 9, 6, 3, 0, 9, 6, 3)
        if xsming == '华盖':
            dy = (4, 1, 10, 7, 4, 1, 10, 7, 4, 1, 10, 7)
        if xsming == '驿马':
            dy = (2, 11, 8, 5, 2, 11, 8, 5, 2, 11, 8, 5)
        if xsming == '劫煞':
            dy = (5, 2, 11, 8, 5, 2, 11, 8, 5, 2, 11, 8)
        if xsming == '亡神':
            dy = (11, 8, 5, 2, 11, 8, 5, 2, 11, 8, 5, 2)
        if xsming == '桃花':
            dy = (9, 6, 3, 0, 9, 6, 3, 0, 9, 6, 3, 0)
        for i in range(4):
            if i != 2:
                if self.dz[i] == dy[dd]:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]
            if i != 0:
                if self.dz[i] == dy[yy]:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 29元辰(大耗)
    # 地支六冲前后，根据性别和年的阴阳决定是前还是后
    def xs_yuanchen(self, xsming=''):
        ch = self.dz[0] + 6
        sh = self.dz[0] + self.gender % 2
        if sh == 0:
            tr = ch - 1
        else:
            tr = ch + 1
        for i in range(4):
            if i != 0:
                if self.dz[i] == tr:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 30孤辰，子年寅、丑年寅、寅年巳、卯年巳、辰年巳、巳年申、午年申、未年申、申年亥、酉年亥、戌年亥、亥年寅
    # 31寡宿，子年、丑年、亥年 见戌10 命带寡宿 年支为寅卯辰见丑1为寡。巳午未的见辰4为寡。申酉戌的在它支见未7为命带寡宿。
    # 32灾煞，将星相冲
    # 申子辰见午6, 亥卯未见酉9, 寅午戌见子0, 巳酉丑见卯3,以年支为主, 四柱地支中见之者为是
    # 33六厄，地支三合局之死地
    # 申子辰水局死地在卯3,寅午戌三合火局，死地在酉9；亥卯未三合木局，死地在午6；巳酉丑三合金局死地在子0
    def xs_Many_06(self, xsming=''):
        if xsming == '孤辰':
            dy = (2, 2, 5, 5, 5, 8, 8, 8, 11, 11, 11, 2)
        if xsming == '寡宿':
            dy = (10, 10, 1, 1, 1, 4, 4, 4, 7, 7, 7, 10)
        if xsming == '灾煞':
            dy = (6, 3, 0, 9, 6, 3, 0, 9, 6, 3, 0, 9)
        if xsming == '六厄':
            dy = (3, 0, 9, 6, 3, 0, 9, 6, 3, 0, 9, 6)
        gc = dy[self.dz[0]]
        for i in range(4):
            if i == 0:
                continue
            if self.dz[i] == gc:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 34勾煞、35绞煞
    # 勾煞和绞煞气一起，阳男阴女，命前三辰为勾，命后三辰为绞。
    def xs_Many_07(self, xsming=''):
        ht = (self.gender + self.dz[0]) % 2
        if ht == 0:
            if xsming == '勾煞':
                sq = (self.dz[0] + 12 -3) % 12
            if xsming == '绞煞':
                sq = (self.dz[0] + 3) % 12
            for i in range(4):
                if i == 0:
                    continue
                if self.dz[i] == sq:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 36童子
    # 命造生在春季或秋季的（以月令算），日支或时支见寅或子的；
    # 命造生在冬季或夏季的（以月令算），日支或时支见卯未或辰的；
    # 年柱纳音为金或木的，日支或时支见午或卯的。
    # 年柱纳音为水或火的，日支或时支见酉或戌的。
    # 年柱纳音为土命的，日支或时支见辰或巳的。
    def xs_tongzi(self, xsming=''):
        ny = self.nayin[0]
        tz = -1
        sy = []
        if 1 < self.dz[1] <= 4:
            sy = sy + [0, 2]
        if 4 < self.dz[1] <= 7:
            sy = sy + [3, 7, 4]
        if ny in self.nywx:
            tz = self.nywx[ny]
        if tz == 0 or tz == 3:  # 木、金
            sy = sy + [6, 3]
        if tz == 1 or tz == 4:  # 火、水
            sy = sy + [9, 10]
        if tz == 2:  # 土
            sy = sy + [4, 5]
        for i in range(4):
            if i in (0, 1):
                continue
            if self.dz[i] in sy:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 37词馆（词馆者，官于翰林，谓之词馆，取其学业精专，文章出类。）
    # 木命见寅，庚寅为正，火命见巳，乙巳为正，土命见巳，丁巳为正，金命见申，壬申为正，水命见亥，癸亥为正。
    def xs_ciguan(self, xsming=''):
        ny = self.nayin[0]
        dy = {0:2, 1:5, 2:5, 3:8, 4:11}
        sy = -1
        if ny in self.nywx:
            sy = self.nywx[ny]
        if sy in dy:
            cg = dy[sy]
            for i in range(4):
                if i == 0:
                    continue
                if self.dz[i] == cg:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 38红鸾（神话传说中的红色仙鸟，命家所说的吉星，主婚配等喜事。）
    # 39天喜
    def xs_Many_08(self, xsming=''):
        if xsming == '红鸾':
            jg = (15 - self.dz[0]) % 12
        if xsming == '天喜':
            jg = (21 - self.dz[0]) % 12
        for i in range(4):
            if i == 0:
                continue
            if self.dz[i] == jg:
                self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 41干禄，甲禄在寅，乙禄在卯，丙戊禄在巳，丁己禄在午，庚禄在申，辛禄在酉，壬祿在亥，癸禄在子。
    def xs_ganlu(self, xsming=''):
        dd = self.tg[2]
        dy = (2, 3, 5, 6, -1, -1, 8, 9, 11, 0)
        gl = dy[dd]
        if gl >= 0:
            for i in range(4):
                if self.dz[i] == gl:
                    self.xing_sha[i] = self.xing_sha[i] + [xsming]

    # 42十灵，甲申、乙酉、丙子、丁丑、戊午、己丑、庚寅、辛卯、壬午、癸未日
    # 43十恶大败，甲辰、乙巳、丙申、丁亥、戊戌、己丑、庚辰、辛巳、壬申、癸亥日
    def xs_Many_09(self, xsming=''):
        if xsming == '十灵':
            dy = ('0-8', '1-9', '2-0', '3-1', '4-6', '5-1', '6-2', '7-3', '8-6', '9-7')
        if xsming == '十恶大败':
            dy = ('0-4', '1-5', '2-8', '3-11', '4-10', '5-1', '6-4', '7-5', '8-8', '9-11')
        sy = str(self.tg[2]) + '-' + str(self.dz[2])
        if sy in dy:
            self.xing_sha[2] = self.xing_sha[2] + [xsming]

    # 开始获取各星煞
    def xs_Funcs_Run(self):
        self.xing_sha = [[], [], [], []]
        for k, xs in enumerate(self.xsha):
            #if xs == '空亡':
            #    self.xs_kongwang(xs)
            if xs in ('天乙', '太极'):
                self.xs_Many_01(xs)
            if xs == '天医':
                self.xs_tianyi1(xs)
            if xs == '天德':
                self.xs_tiande(xs)
            if xs == '月德':
                self.xs_yuede(xs)
            if xs == '禄神':
                self.xs_lushen(xs)
            if xs == '羊刃':
                self.xs_yangren(xs)
            if xs == '孤鸾':
                self.xs_guluan(xs)
            if xs == '三奇':
                self.xs_sanqi(xs)
            if xs == '天赦':
                self.xs_tianshe(xs)
            if xs == '德秀':
                self.xs_dexiu(xs)
            if xs == '魁罡':
                self.xs_kuigang(xs)
            if xs == '金神':
                self.xs_jinshen(xs)
            if xs in ('天罗', '地网'):
                self.xs_Many_02(xs)
            if xs == '文昌':
                self.xs_wenchang(xs)
            if xs == '金舆':
                self.xs_jinyu(xs)
            if xs == '福星':
                self.xs_fuxing(xs)
            if xs in ('国印', '天厨'):
                self.xs_Many_03(xs)
            if xs == '学堂':
                self.xs_xuetang(xs)
            if xs in ('红艳', '流霞'):
                self.xs_Many_04(xs)
            if xs in ('将星', '华盖', '驿马', '劫煞', '亡神', '桃花'):
                self.xs_Many_05(xs)
            if xs == '元辰(大耗)':
                self.xs_yuanchen(xs)
            if xs in ('孤辰', '寡宿', '灾煞', '六厄'):
                self.xs_Many_06(xs)
            if xs in ('勾煞', '绞煞'):
                self.xs_Many_07(xs)
            if xs == '童子':
                self.xs_tongzi(xs)
            if xs == '词馆':
                self.xs_ciguan(xs)
            if xs in ('红鸾', '天喜'):
                self.xs_Many_08(xs)
            if xs == '干禄':
                self.xs_ganlu(xs)
            if xs in ('十灵', '十恶大败'):
                self.xs_Many_09(xs)
        return self.xing_sha
